package com.zmn.plat.business.impl.channel.promotion;

import com.alibaba.dubbo.config.annotation.Reference;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.mcc.cas.web.StaffAdminService;
import com.zmn.oms.dubbo.dto.zmn.third.toutiao.ToutiaoCompanyAccountDIO;
import com.zmn.oms.dubbo.interfaces.zmn.third.toutiao.ToutiaoRemoteService;
import com.zmn.plat.business.interfaces.channel.promotion.ChannelPromotionBService;
import com.zmn.plat.common.exception.PlatException;
import com.zmn.plat.dubbo.utils.DubboConsts;
import com.zmn.plat.model.entity.channel.promotion.ChannelPromotion;
import com.zmn.plat.model.entity.channel.promotion.ChannelPromotionQuery;
import com.zmn.plat.services.interfaces.channel.promotion.ChannelPromotionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 渠道推广BServiceImpl
 * 
 * @author linfeng
 * @since 2020/11/23 11:44
 */
@Service
@Slf4j
public class ChannelPromotionBServiceImpl implements ChannelPromotionBService {
    @Resource
    protected ChannelPromotionService channelPromotionService;

    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private ToutiaoRemoteService toutiaoRemoteService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addEditChannePromotion(ChannelPromotion channelPromotion) {
        Date now = DateUtil.getNow();
        String operator = StaffAdminService.currentStaff().getRealName();
        Integer relateId = channelPromotion.getRelateId();

        if (NumberUtil.isNullOrZero(relateId)) {
            if (Objects.equals(GlobalConsts.YES, channelPromotion.getStatus())) {
                checkUniquenessForAdd(channelPromotion);
            }
            channelPromotion.setCreater(operator);
            channelPromotion.setCreateTime(now);
            channelPromotion.setUpdater(operator);
            channelPromotion.setUpdateTime(now);
            channelPromotionService.insert(channelPromotion);
            relateId = channelPromotion.getRelateId();
        } else {
            if (Objects.equals(GlobalConsts.YES, channelPromotion.getStatus())) {
                checkUniquenessForModify(channelPromotion);
            }
            channelPromotion.setUpdater(operator);
            channelPromotion.setUpdateTime(now);
            channelPromotionService.updateByKey(channelPromotion);
        }

        if (Objects.equals(GlobalConsts.YES, channelPromotion.getStatus())) {
            ToutiaoCompanyAccountDIO toutiaoCompanyAccountDIO = new ToutiaoCompanyAccountDIO();
            toutiaoCompanyAccountDIO.setChannelId(channelPromotion.getChannelId());
            toutiaoCompanyAccountDIO.setName(channelPromotion.getCompanyName());
            toutiaoCompanyAccountDIO.setSecret(channelPromotion.getSecretKey());
            toutiaoCompanyAccountDIO.setToken(channelPromotion.getToken());

            List<ToutiaoCompanyAccountDIO> data = new ArrayList<>();
            data.add(toutiaoCompanyAccountDIO);

            // 通知oms创建账户
            ResponseDTO responseDTO = toutiaoRemoteService.addCompanyAccount(data);
            if (!responseDTO.isSuccess()) {
                log.error("新建渠道今日头条推广-状态启用-通知oms添加公司账号失败");
            }
        } else if (Objects.equals(GlobalConsts.NO, channelPromotion.getStatus())) {
            List<String> secretKeyList = new ArrayList<>();
            secretKeyList.add(channelPromotion.getSecretKey());
            ResponseDTO responseDTO = toutiaoRemoteService.delCompanyAccount(secretKeyList);
            if (!responseDTO.isSuccess()) {
                log.error("修改渠道今日头条推广-状态停用-通知oms删除公司账号失败");
            }
        }

        return relateId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(String ids, Integer status) {
        List<Integer> arrayIds = StringUtil.convertStrsToList(ids);
        List<ChannelPromotion> result = channelPromotionService.listByRelateIds(arrayIds);

        if (Objects.equals(GlobalConsts.YES, status)) {
            List<String> accoutIdList = result.stream().map(e -> e.getAccountId()).collect(Collectors.toList());
            ChannelPromotionQuery query = new ChannelPromotionQuery();
            query.setAccountIdList(accoutIdList);
            query.setStatus(GlobalConsts.YES);
            List<ChannelPromotion> list = channelPromotionService.listByQuery(query);
            if (CollectionUtil.isNotNullOrEmpty(list)) {
                throw new PlatException("账户ID为：" + list.get(0).getAccountId() + "不能重复");
            }

            List<String> accountNameList = result.stream().map(e -> e.getAccountName()).collect(Collectors.toList());
            query = new ChannelPromotionQuery();
            query.setAccountNameList(accountNameList);
            query.setStatus(GlobalConsts.YES);
            list = channelPromotionService.listByQuery(query);
            if (CollectionUtil.isNotNullOrEmpty(list)) {
                throw new PlatException("账户名称为：" + list.get(0).getAccountName() + "不能重复");
            }

            List<String> secretKeyList = result.stream().map(e -> e.getSecretKey()).collect(Collectors.toList());
            query = new ChannelPromotionQuery();
            query.setSecretKeyList(secretKeyList);
            query.setStatus(GlobalConsts.YES);
            list = channelPromotionService.listByQuery(query);
            if (CollectionUtil.isNotNullOrEmpty(list)) {
                throw new PlatException("密钥为：" + list.get(0).getSecretKey() + "不能重复");
            }

            List<String> tokenList = result.stream().map(e -> e.getToken()).collect(Collectors.toList());
            query = new ChannelPromotionQuery();
            query.setTokenList(tokenList);
            query.setStatus(GlobalConsts.YES);
            list = channelPromotionService.listByQuery(query);
            if (CollectionUtil.isNotNullOrEmpty(list)) {
                throw new PlatException("token为：" + list.get(0).getToken() + "不能重复");
            }
        }

        channelPromotionService.updateStatusBatch(arrayIds, status, StaffAdminService.currentStaff().getRealName());

        if (Objects.equals(GlobalConsts.YES, status)) {
            List<ToutiaoCompanyAccountDIO> data = new ArrayList<>();
            for (ChannelPromotion innerData: result) {
                ToutiaoCompanyAccountDIO toutiaoCompanyAccountDIO = new ToutiaoCompanyAccountDIO();
                toutiaoCompanyAccountDIO.setChannelId(innerData.getChannelId());
                toutiaoCompanyAccountDIO.setName(innerData.getCompanyName());
                toutiaoCompanyAccountDIO.setSecret(innerData.getSecretKey());
                toutiaoCompanyAccountDIO.setToken(innerData.getToken());
                data.add(toutiaoCompanyAccountDIO);
            }

            // 通知oms添加公司账号
            if (CollectionUtil.isNotNullOrEmpty(data)) {
                ResponseDTO responseDTO = toutiaoRemoteService.addCompanyAccount(data);
                if (!responseDTO.isSuccess()) {
                    log.error("启用渠道今日头条推广状态-通知oms添加公司账号失败");
                }
            }
        } else if (Objects.equals(GlobalConsts.NO, status)) {
            List<String> secretKeyList = result.stream().map(e -> e.getSecretKey()).collect(Collectors.toList());

            // 通知oms删除公司账号
            if (CollectionUtil.isNotNullOrEmpty(secretKeyList)) {
                ResponseDTO responseDTO = toutiaoRemoteService.delCompanyAccount(secretKeyList);
                if (!responseDTO.isSuccess()) {
                    log.error("停用渠道今日头条推广状态-通知oms删除公司账号失败");
                }
            }
        }
    }

    @SuppressWarnings("Duplicates")
    private void checkUniquenessForAdd(ChannelPromotion channelPromotion) {
        ChannelPromotionQuery query = new ChannelPromotionQuery();
        query.setAccountId(channelPromotion.getAccountId());
        query.setStatus(GlobalConsts.YES);
        List<ChannelPromotion> list = channelPromotionService.listByQuery(query);
        if (CollectionUtil.isNotNullOrEmpty(list)) {
            throw new PlatException("账户ID已经存在");
        }

        query.setAccountId(null);
        query.setAccountName(channelPromotion.getAccountName());
        list = channelPromotionService.listByQuery(query);
        if (CollectionUtil.isNotNullOrEmpty(list)) {
            throw new PlatException("账户名称已经存在");
        }

        query.setAccountName(null);
        query.setToken(channelPromotion.getToken());
        list = channelPromotionService.listByQuery(query);
        if (CollectionUtil.isNotNullOrEmpty(list)) {
            throw new PlatException("token已经存在");
        }

        query.setToken(null);
        query.setSecretKey(channelPromotion.getSecretKey());
        list = channelPromotionService.listByQuery(query);
        if (CollectionUtil.isNotNullOrEmpty(list)) {
            throw new PlatException("密钥已经存在");
        }
    }

    @SuppressWarnings("Duplicates")
    private void checkUniquenessForModify(ChannelPromotion channelPromotion) {
        ChannelPromotionQuery query = new ChannelPromotionQuery();
        query.setAccountId(channelPromotion.getAccountId());
        query.setStatus(GlobalConsts.YES);
        List<ChannelPromotion> list = channelPromotionService.listByQuery(query).stream().filter(e -> !Objects.equals(e.getRelateId(), channelPromotion.getRelateId())).collect(Collectors.toList());
        if (CollectionUtil.isNotNullOrEmpty(list)) {
            throw new PlatException("账户ID已经存在");
        }

        query.setAccountId(null);
        query.setAccountName(channelPromotion.getAccountName());
        list = channelPromotionService.listByQuery(query).stream().filter(e -> !Objects.equals(e.getRelateId(), channelPromotion.getRelateId())).collect(Collectors.toList());
        if (CollectionUtil.isNotNullOrEmpty(list)) {
            throw new PlatException("账户名称已经存在");
        }

        query.setAccountName(null);
        query.setToken(channelPromotion.getToken());
        list = channelPromotionService.listByQuery(query).stream().filter(e -> !Objects.equals(e.getRelateId(), channelPromotion.getRelateId())).collect(Collectors.toList());
        if (CollectionUtil.isNotNullOrEmpty(list)) {
            throw new PlatException("token已经存在");
        }

        query.setToken(null);
        query.setSecretKey(channelPromotion.getSecretKey());
        list = channelPromotionService.listByQuery(query).stream().filter(e -> !Objects.equals(e.getRelateId(), channelPromotion.getRelateId())).collect(Collectors.toList());
        if (CollectionUtil.isNotNullOrEmpty(list)) {
            throw new PlatException("密钥已经存在");
        }
    }
}
